
#include <cassert>
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;

template <typename T>
struct base
{
    T a;
    void GetType() { cout << typeid(T).name() << endl; }
    base(T b) : a{b} {}
};


template <typename T, bool type = false>
struct c1;

// 这样写也可以  而且不用上面的声明了
// template <typename T, bool value = false>
// struct c1 : base<T>

template <typename T>
// 偏特化应该这么写  见 c++ templates 2nd  35页
struct c1<T, false> : base<T>
{
    T b;
    c1(T a, T c) : base<T>(a), b{c} {}
    void pnt()
    {
        base<T>::GetType();
        cout << b << endl;
        cout << "false\n";
    }
};

template <typename T>
struct c1<T, true> : base<T>
{
    T b;
    c1(T a, T c) : base<T>(a), b{c} {}
    void pnt()
    {
        base<T>::GetType();
        cout << b << endl;
        cout << "true\n";
    }
};

////////////////////////////////////////////////

int main()
{
    // c1<false> c2;
    // c1<true> c3;
    // c2.pnt();
    // c3.pnt();

    // int a;
    // auto str =  typeid(typeid(typeid(a).name()).name()).name();
    // cout << str << endl;

    c1<int, false> cfalse(2, 3), c2(11, 12);
    c1<double, true> ctrue(4, 5);
    cfalse.GetType();
    cfalse.pnt();

    c2.GetType();
    c2.pnt();

    ctrue.GetType();
    ctrue.pnt();

    c1<double> c3(22, 33);
    c3.GetType();
    c3.pnt();
    return 0;
}